﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NUnit.Framework;
using SistemaDeBastanteodePoderes.Persistencia;
using SistemaDeBastanteodePoderes.Dominio;

namespace SistemaDeBastanteodePoderes.Pruebas.DAO
{

    [TestFixture]
    public class Test_H1_1_TipoEmpresaDAO
    {
        ITipoEmpresaDAO tipoEmpresaDAO = null; // Utilizamos una referencia a la interfaz
        TipoEmpresa tipoCreado = null;

        [TestFixtureSetUp]
        public void InicializarPruebas()
        {
            tipoEmpresaDAO = new Persistencia.NH.TipoEmpresaDAO(); // Elegimos la implementación DAO a probar (ADO ó NHibernate)
            foreach (TipoEmpresa tipo in tipoEmpresaDAO.ListarTodos())
                tipoEmpresaDAO.Eliminar(tipo);
        }

        [Test]
        public void Test1_Crear()
        {
            TipoEmpresa tipoACrear = new TipoEmpresa();
            // 1. Validar que ocurra un error si no se ingresa la Abreviacion del tipo de empresa
            tipoACrear.Abreviacion = null;
            tipoACrear.Descripcion = "DESCRIPCION";
            Assert.Catch<Exception>(delegate
            {
                tipoCreado = tipoEmpresaDAO.Crear(tipoACrear);
            });

            // 2. Validar que ocurra un error si no se ingresa la Descripcion del tipo de empresa
            tipoACrear.Abreviacion = "ABREV";
            tipoACrear.Descripcion = null;
            Assert.Catch<Exception>(delegate
            {
                tipoCreado = tipoEmpresaDAO.Crear(tipoACrear);
            });

            // 3. Validar que se crea correctamente (sin error) el tipo de empresa
            tipoACrear.Abreviacion = "SAC";
            tipoACrear.Descripcion = "SOCIEDAD ANONIMA CERRADA";
            Assert.DoesNotThrow(delegate
            {
                tipoCreado = tipoEmpresaDAO.Crear(tipoACrear);
            });

            // 4. Validar que se crea correctamente (sin error) un segundo tipo de empresa
            tipoACrear.Abreviacion = "SAA";
            tipoACrear.Descripcion = "SOCIEDAD ANONIMA ABIERTA";
            Assert.DoesNotThrow(delegate
            {
                tipoCreado = tipoEmpresaDAO.Crear(tipoACrear);
            });

            // 5. Validar que el tipo creado no sea nulo, que tenga un código mayor que 0 y que la abreviación sea la ingresada
            Assert.IsNotNull(tipoCreado);
            Assert.Greater(tipoCreado.Codigo, 0);
            Assert.AreEqual(tipoCreado.Abreviacion, tipoACrear.Abreviacion);
        }
        [Test]
        public void Test2_Obtener()
        {
            TipoEmpresa obtenido = null;
            // 1. Validar que si se intenta obtener un tipo de empresa inexistente se retorne null
            Assert.DoesNotThrow(delegate
            {
                obtenido = tipoEmpresaDAO.Obtener(1000);
            });
            Assert.IsNull(obtenido);
            // 2. Validar que se obtenga un tipo de empresa correctamente (sin error)
            Assert.DoesNotThrow(delegate
            {
                obtenido = tipoEmpresaDAO.Obtener(tipoCreado.Codigo);
            });
            Assert.IsNotNull(obtenido);
        }
        [Test]
        public void Test3_Modificar()
        {
            TipoEmpresa tipoAModificar = tipoEmpresaDAO.Obtener(tipoCreado.Codigo);
            TipoEmpresa tipoModificado = null;
            // 1. Validar que ocurre un error si la Abreviacion ingresada es nula
            tipoAModificar.Abreviacion = null;
            Assert.Catch<Exception>(delegate
            {
                tipoModificado = tipoEmpresaDAO.Modificar(tipoAModificar);
            });
            // 2. Validar que se modifica correctamente (sin error) el tipo de empresa
            tipoAModificar.Abreviacion = "SRL";
            Assert.DoesNotThrow(delegate
            {
                tipoModificado = tipoEmpresaDAO.Modificar(tipoAModificar);
            });
            // 3. Validar que el tipo de empresa modificado no sea nulo y la Abreviacion sea la ingresada
            Assert.IsNotNull(tipoModificado);
            Assert.AreEqual(tipoAModificar.Abreviacion, tipoModificado.Abreviacion);
        }
        [Test]
        public void Test4_Eliminar()
        {
            TipoEmpresa tipoAEliminar = tipoEmpresaDAO.Obtener(tipoCreado.Codigo);
            // 1. Validar que ocurra un error si se intenta eliminar un tipo de empresa inexistente
            Assert.Catch<Exception>(delegate
            {
                tipoEmpresaDAO.Eliminar(null);
            });
            // 2. Validar que se elimine un tipo de empresa correctamente
            Assert.DoesNotThrow(delegate
            {
                tipoEmpresaDAO.Eliminar(tipoAEliminar);
            });
            // 3. Validar que el tipo de empresa eliminado ya no exista
            TipoEmpresa tipoEliminado = tipoEmpresaDAO.Obtener(tipoCreado.Codigo);
            Assert.IsNull(tipoEliminado);
        }
        [Test]
        public void Test5_Listar()
        {
            tipoEmpresaDAO.Crear(new TipoEmpresa() { Abreviacion = "TP1", Descripcion = "TIPO 1" });
            tipoEmpresaDAO.Crear(new TipoEmpresa() { Abreviacion = "TP2", Descripcion = "TIPO 2" });
            // 1. Validar que se listen sin errores los tipos de empresa creados
            ICollection<TipoEmpresa> tiposExistentes = null;
            Assert.DoesNotThrow(delegate
            {
                tiposExistentes = tipoEmpresaDAO.ListarTodos();
            });
            // 2. Validar que retorne los 2 tipos de empresa creados
            Assert.GreaterOrEqual(tiposExistentes.Count, 2);
            // 3. Validar que la Abreviacion de cada tipo de empresa no sea nula
            foreach (TipoEmpresa tipo in tiposExistentes)
                Assert.IsNotNull(tipo.Abreviacion);
        }

        [TestFixtureTearDown]
        public void FinalizarPruebas()
        {
            foreach (TipoEmpresa tipo in tipoEmpresaDAO.ListarTodos())
                tipoEmpresaDAO.Eliminar(tipo);
            Persistencia.NH.NHibernateHelper.CerrarFabrica();
        }
    }

}